/*
 * main.cpp
 *
 *  Created on: Aug 26, 2011
 *      Author: Jon
 */

//	DDRB = _BV(PB0);//Pinmode(8, OUTPUT);
//	PORTB = _BV(PB0); //digitalWrite(8, HIGH);


#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define delay(x) _delay_ms(x)
void delay_us(unsigned long delay)
{
	while(delay--) asm volatile("nop");
}

#define THREE_HOUR_PIN PC5
#define FIVE_HOUR_PIN PC1
#define SEVEN_HOUR_PIN PC2
#define NINE_HOUR_PIN PC3
#define TWELVE_HOUR_PIN	PC4
#define RELEASE_PIN PC0

#define ALL_BUTTON_MASK 0x1F
#define THREE_HOUR_MASK 0x01
#define FIVE_HOUR_MASK 0x02
#define SEVEN_HOUR_MASK 0x04
#define NINE_HOUR_MASK 0X08


typedef enum TIMES
{
	THREE = 3/*3*3600*/,
	FIVE = 17999/*5*3600*/,
	SEVEN = 25198/*7*3600*/,
	NINE = 32398/*9*3600*/,
	TWELVE = 43198/*12*3600*/
}TIMES;

void setupTimer()
{
  TCCR1A = _BV(COM1B1);
  TCCR1B = _BV(CS12)| _BV(CS10) | _BV(WGM12);//--CLK/1024 = 7812.5Hz
  /*Compare Match every 1 second*/
  uint16_t counts = 7813;//attiny88 = 1.000064 (1sec)
  OCR1B = counts;
  TIMSK1 = _BV(OCIE1B);
}


void step(uint8_t steps, uint8_t direction, volatile uint8_t * motor_pos)
{
  //uint8_t motor_step[4] = {0x1a, 0x16, 0x15, 0x19};//full step
  uint8_t motor_step[8] = {0x18, 0x1a, 0x12, 0x16, 0x14, 0x15, 0x11, 0x19};//half step
  uint8_t motor_position = *motor_pos;
  for(int i=0;i<steps;i++)
  {
    PORTD = motor_step[motor_position];
    delay(20);  // delay time for each step
    if(direction)
    {
      motor_position++;
    }
    else
    {
      motor_position--;
    }
    //motor_position = motor_position & 0x03;//full step
    motor_position = motor_position & 0x07;//half step
  }
  *motor_pos = motor_position;
  PORTD = 0x00;
}

volatile uint32_t seconds = 0; //Max time is: ~18 hours
volatile uint32_t time_delay = TWELVE;
volatile uint8_t motor_position = 0;

int main(void)
{

	//Buttons
	DDRC &= ~_BV(PC0) | ~_BV(PC1) | ~_BV(PC2) | ~_BV(PC3) | ~_BV(PC4) | ~_BV(PC5);//inputs
	PORTC = _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3) | _BV(PC4) | _BV(PC5);

	//Motor Pins
	DDRD = 0xff;//pinMode(0-7, OUTPUT);

	//LEDS
	DDRB = 0xff;

	_delay_ms(500);

	cli();
	setupTimer();
	_delay_ms(500);
	sei();
	uint8_t input;
	while(1)
	{
		input= PINC;
		if(bit_is_clear(PINC, THREE_HOUR_PIN))
		{
			time_delay = THREE;
			PORTB &= ~0xff;//Clear
			PORTD &= ~_BV(PD7);
			PORTB |= _BV(PB0);
			while(bit_is_clear(PINC, THREE_HOUR_PIN));
		}
		if(bit_is_clear(PINC, FIVE_HOUR_PIN))
		{
			time_delay = FIVE;
			PORTB &= ~0xff;//Clear
			PORTD &= ~_BV(PD7);
			PORTB |= _BV(PB1);
			while(bit_is_clear(PINC, FIVE_HOUR_PIN));
		}
		if(bit_is_clear(PINC,SEVEN_HOUR_PIN))
		{
			time_delay = SEVEN;
			PORTB &= ~0xff;//Clear
			PORTD &= ~_BV(PD7);
			PORTB |= _BV(PB3);
			while(bit_is_clear(PINC,SEVEN_HOUR_PIN));
		}
		if(bit_is_clear(PINC, NINE_HOUR_PIN))
		{
			time_delay = NINE;
			PORTB &= ~0xff;//Clear
			PORTD &= ~_BV(PD7);
			PORTB |= _BV(PB4);
			while(bit_is_clear(PINC, NINE_HOUR_PIN));
		}
		if(bit_is_clear(PINC, TWELVE_HOUR_PIN))
		{
			time_delay = TWELVE;
			PORTB &= ~0xff;//Clear
			PORTD &= ~_BV(PD7);
			PORTB |= _BV(PB5);
			while(bit_is_clear(PINC, TWELVE_HOUR_PIN));
		}
		if(bit_is_clear(PINC, RELEASE_PIN))
		{
			PORTD &= ~_BV(PD7);
			PORTD |=  _BV(PD7);
			//step(67, 1, &motor_position);//full step
			step(67, 1, &motor_position);//half step
		}
    }
	return 0;
}



ISR(TIMER1_COMPB_vect)
{
	seconds++;
	if(seconds>=time_delay)
	{
		//step(67, 1, &motor_position);//full step
		step(67, 1, &motor_position);//half step
		seconds = 0;
	}
	TCNT1=0;
}
